<script src="../../dist/vue-vapor.global.js"></script>
<link
  rel="stylesheet"
  href="../../../../node_modules/todomvc-app-css/index.css"
/>

<div id="app"></div>

<script>
  const {
    createVaporApp,
    defineComponent,
    reactive,
    computed,
    watchEffect,
    onMounted,
    onUnmounted,
    nextTick,
  } = VueVapor

  const STORAGE_KEY = 'todos-vuejs-3.x'
  const todoStorage = {
    fetch() {
      const todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')
      todos.forEach((todo, index) => {
        todo.id = index
      })
      todoStorage.uid = todos.length
      return todos
    },
    save(todos) {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))
    },
  }

  const filters = {
    all(todos) {
      return todos
    },
    active(todos) {
      return todos.filter(todo => {
        return !todo.completed
      })
    },
    completed(todos) {
      return todos.filter(function (todo) {
        return todo.completed
      })
    },
  }

  function pluralize(n) {
    return n === 1 ? 'item' : 'items'
  }

  const _sfc_main = defineComponent({
    setup() {
      const state = reactive({
        todos: todoStorage.fetch(),
        editedTodo: null,
        newTodo: '',
        beforeEditCache: '',
        visibility: 'all',
        remaining: computed(() => {
          return filters.active(state.todos).length
        }),
        remainingText: computed(() => {
          return ` ${pluralize(state.remaining)} left`
        }),
        filteredTodos: computed(() => {
          return filters[state.visibility](state.todos)
        }),
        allDone: computed({
          get: function () {
            return state.remaining === 0
          },
          set: function (value) {
            state.todos.forEach(todo => {
              todo.completed = value
            })
          },
        }),
      })

      watchEffect(() => {
        todoStorage.save(state.todos)
      })

      onMounted(() => {
        window.addEventListener('hashchange', onHashChange)
        onHashChange()
      })

      onUnmounted(() => {
        window.removeEventListener('hashchange', onHashChange)
      })

      function onHashChange() {
        const visibility = window.location.hash.replace(/#\/?/, '')
        if (filters[visibility]) {
          state.visibility = visibility
        } else {
          window.location.hash = ''
          state.visibility = 'all'
        }
      }

      function addTodo() {
        const value = state.newTodo && state.newTodo.trim()
        if (!value) {
          return
        }
        state.todos.push({
          id: todoStorage.uid++,
          title: value,
          completed: false,
        })
        state.newTodo = ''
      }

      function removeTodo(todo) {
        state.todos.splice(state.todos.indexOf(todo), 1)
      }

      async function editTodo(todo) {
        state.beforeEditCache = todo.title
        state.editedTodo = todo
        await nextTick()
        document.getElementById(`todo-${todo.id}-input`).focus()
      }

      function doneEdit(todo) {
        if (!state.editedTodo) {
          return
        }
        state.editedTodo = null
        todo.title = todo.title.trim()
        if (!todo.title) {
          removeTodo(todo)
        }
      }

      function cancelEdit(todo) {
        state.editedTodo = null
        todo.title = state.beforeEditCache
      }

      function removeCompleted() {
        state.todos = filters.active(state.todos)
      }

      return {
        state,
        addTodo,
        removeTodo,
        editTodo,
        doneEdit,
        cancelEdit,
        removeCompleted,
      }
    },
  })

  const {
    children: _children,
    vModelText: _vModelText,
    withDirectives: _withDirectives,
    vShow: _vShow,
    next: _next,
    delegate: _delegate,
    on: _on,
    renderEffect: _renderEffect,
    setDynamicProp: _setDynamicProp,
    setText: _setText,
    setClass: _setClass,
    createFor: _createFor,
    insert: _insert,
    delegateEvents: _delegateEvents,
    template: _template,
  } = VueVapor
  const t0 = _template(
    '<li><div class="view"><input class="toggle" type="checkbox"><label></label><button class="destroy"></button></div><input class="edit" type="text"></li>',
  )
  const t1 = _template(
    '<section class="todoapp"><header class="header"><h1>todos</h1><input class="new-todo" autofocus autocomplete="off" placeholder="What needs to be done?"></header><section class="main"><input id="toggle-all" class="toggle-all" type="checkbox"><label for="toggle-all">Mark all as complete</label><ul class="todo-list"></ul></section><footer class="footer"><span class="todo-count"><strong></strong><span></span></span><ul class="filters"><li><a href="#/all">All</a></li><li><a href="#/active">Active</a></li><li><a href="#/completed">Completed</a></li></ul><button class="clear-completed"> Clear completed </button></footer></section>',
  )
  _delegateEvents('keyup', 'dblclick', 'click', 'input')

  function _sfc_render(_ctx) {
    const n18 = t1()
    const n0 = _children(n18, 0, 1)
    _withDirectives(n0, [[_vModelText, () => _ctx.state.newTodo]])
    const n10 = _children(n18, 1)
    _withDirectives(n10, [[_vShow, () => _ctx.state.todos.length]])
    const n1 = n10.firstChild
    const n9 = _next(n1, 2)
    const n17 = n10.nextSibling
    _withDirectives(n17, [[_vShow, () => _ctx.state.todos.length]])
    const n11 = _children(n17, 0, 0)
    const n12 = n11.nextSibling
    const n13 = _children(n17, 1, 0, 0)
    const n14 = _children(n17, 1, 1, 0)
    const n15 = _children(n17, 1, 2, 0)
    const n16 = _children(n17, 2)
    _withDirectives(n16, [
      [_vShow, () => _ctx.state.todos.length > _ctx.state.remaining],
    ])
    _delegate(
      n0,
      'update:modelValue',
      () => $event => (_ctx.state.newTodo = $event),
    )
    _delegate(n0, 'keyup', () => _ctx.addTodo, {
      keys: ['enter'],
    })
    _on(
      n1,
      'change',
      () => $event => (_ctx.state.allDone = $event.target.checked),
    )
    const n2 = _createFor(
      () => _ctx.state.filteredTodos,
      _ctx2 => {
        const n8 = t0()
        const n4 = _children(n8, 0, 0)
        const n5 = n4.nextSibling
        const n6 = n5.nextSibling
        const n7 = _children(n8, 1)
        _on(
          n4,
          'change',
          () => $event => (_ctx2[0].completed = $event.target.checked),
        )
        _delegate(n5, 'dblclick', () => $event => _ctx.editTodo(_ctx2[0]))
        _delegate(n6, 'click', () => $event => _ctx.removeTodo(_ctx2[0]))
        _delegate(
          n7,
          'input',
          () => $event => (_ctx2[0].title = $event.target.value),
        )
        _on(n7, 'blur', () => $event => _ctx.doneEdit(_ctx2[0]))
        _delegate(n7, 'keyup', () => $event => _ctx.doneEdit(_ctx2[0]), {
          keys: ['enter'],
        })
        _delegate(n7, 'keyup', () => $event => _ctx.cancelEdit(_ctx2[0]), {
          keys: ['escape'],
        })
        _renderEffect(() => _setDynamicProp(n4, 'checked', _ctx2[0].completed))
        _renderEffect(() => {
          _setText(n5, _ctx2[0].title)
          _setDynamicProp(n7, 'value', _ctx2[0].title)
        })
        _renderEffect(() =>
          _setDynamicProp(n7, 'id', `todo-${_ctx2[0].id}-input`),
        )
        _renderEffect(() =>
          _setClass(n8, [
            'todo',
            {
              completed: _ctx2[0].completed,
              editing: _ctx2[0] === _ctx.state.editedTodo,
            },
          ]),
        )
        return n8
      },
      todo => todo.id,
    )
    _insert(n2, n9)
    _delegate(n16, 'click', () => _ctx.removeCompleted)
    _renderEffect(() => _setDynamicProp(n1, 'checked', _ctx.state.allDone))
    _renderEffect(() => _setText(n11, _ctx.state.remaining))
    _renderEffect(() => _setText(n12, _ctx.state.remainingText))
    _renderEffect(() =>
      _setClass(n13, { selected: _ctx.state.visibility === 'all' }),
    )
    _renderEffect(() =>
      _setClass(n14, { selected: _ctx.state.visibility === 'active' }),
    )
    _renderEffect(() =>
      _setClass(n15, { selected: _ctx.state.visibility === 'completed' }),
    )
    return n18
  }

  _sfc_main.render = _sfc_render
  const app = createVaporApp(_sfc_main, {})
  app.mount('#app')
</script>
